using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
using GeoFramework.IO;
using GeoFramework.IO.Serial;
#if !PocketPC || DesignTime || Framework20
using System.ComponentModel;
#endif
#if PocketPC
using GeoFramework.Licensing;
#endif

namespace GeoFramework.Controls
{
	public sealed class GpsDeviceItem
	{
		private string pText;
		private object pItem;
		
        /// <summary>
        /// Returns the name of the GPS device in the combo box.
        /// </summary>
		public string Text
		{
			get
			{
				return pText;
			}
		}

        /// <summary>
        /// Returns the Device object associated with the GPS device.
        /// </summary>
		public object Item
		{
			get
			{
				return pItem;
			}
		}

        /// <summary>
        /// Creates a new instance using the specified GPS device name and Device object.
        /// </summary>
        /// <param name="item"></param>
        /// <param name="text"></param>
		public GpsDeviceItem(object item, string text)
		{
			pItem = item;
			pText = text;
		}
	}

	/// <summary>
	/// Summary description for SerialDeviceComboBox.
	/// </summary>
#if !PocketPC || DesignTime
	[ToolboxBitmap(typeof(ComboBox))]
#endif
#if Framework20
#if !PocketPC
    [ToolboxItem(true)]
#endif
    //[DesignTimeVisible(true)]
#endif
	[CLSCompliant(false)]
    public sealed class GpsDeviceComboBox : System.Windows.Forms.ComboBox 
	{
		/// <summary> 
		/// Required Designer variable.
		/// </summary>
		//private System.ComponentModel.Container components = null;

        /// <summary>
        /// Creates a new instance.
        /// </summary>
		public GpsDeviceComboBox()
		{
			// This call is required by the Windows.Forms Form Designer.
			//InitializeComponent();

#if !Smartphone && !Smartphone20
			DropDownStyle = ComboBoxStyle.DropDownList;
#endif

			// Add devices to the list
			this.DisplayMember = "Text";
			this.ValueMember = "Item";
            
            // Remove all items?
			Items.Clear();

#if PocketPC && !Framework20
			// Hook into the altitude changed event
			Devices.DeviceDetected += new DeviceEventHandler(Computer_DeviceDetected);
#endif

			if(Devices.IsDetectionComplete)
			{
                lock (Devices.GpsDevices.SyncRoot)
                {
                    foreach (Device device in Devices.GpsDevices)
                    {
                        AddDevice(device);
                    }
                }
			}
		}

#if PocketPC && !Framework20
		protected override void Dispose(bool disposing)
		{
			try
			{
				GC.SuppressFinalize(this);

				// Hook into the altitude changed event
				Devices.DeviceDetected -= new DeviceEventHandler(Computer_DeviceDetected);
			}
			catch
			{
			}
		}

		~GpsDeviceComboBox()
		{
			Dispose();
		}
#endif


		private void AddDevice(Device device)
		{
			// Make a new GPS item
			GpsDeviceItem NewItem = new GpsDeviceItem(device, device.ToString());
			// If it already contains the item, exit
			if(Items.Contains(NewItem))
				return;
			// Add the new item
			Items.Add(NewItem);
			// Set the selected index if necessary
			if(this.SelectedIndex == -1)
				this.SelectedIndex = 0;
		}

#if !PocketPC || Framework20
        protected override void OnHandleCreated(EventArgs e)
        {
            try
            {
                base.OnHandleCreated(e);

                // Only hook into events if we're at run-time.  Hooking events
                // at design-time can actually cause errors in the WF Designer.
                if (LicenseManager.CurrentContext.UsageMode == LicenseUsageMode.Runtime)
                {
                    Devices.DeviceDetected += new DeviceEventHandler(Computer_DeviceDetected);
                }
            }
            catch
            {
            }
        }

        protected override void OnHandleDestroyed(EventArgs e)
        {
            try
            {
                // Only hook into events if we're at run-time.  Hooking events
                // at design-time can actually cause errors in the WF Designer.
                if (LicenseManager.CurrentContext.UsageMode == LicenseUsageMode.Runtime)
                {
                    Devices.DeviceDetected -= new DeviceEventHandler(Computer_DeviceDetected);
                }
            }
            catch
            {
            }
            finally
            {
                base.OnHandleDestroyed(e);
            }
        }
#endif

        //#region Component Designer generated code
        ///// <summary> 
        ///// Required method for Designer support - do not modify 
        ///// the contents of this method with the code editor.
        ///// </summary>
        //private void InitializeComponent()
        //{
        //    components = new System.ComponentModel.Container();
        //}
        //#endregion		

		private void Computer_DeviceDetected(object sender, DeviceEventArgs e)
		{
			AddDevice(e.Device);
		}
	}
}
